/*
 * S_Operation.cpp
 *
 *  Created on: Jul 30, 2011
 *      Author: ofrenk33
 */

#include "Operation.h"
using namespace std;

/* ctor */
S_Operation::S_Operation(int argc, char *argv[]) : Operation(argc, argv) {
	_type = SN;
	_opOrder = atoi(argv[1] + 1);
	if (_opOrder % 2 != 0) {
		cerr << "ERROR: Only even values of n are allowed" << endl;
		exit(1);
	}
	_opName = "S";
	_opName += argv[1] + 1;
	_opName += " SYMMETRY";

	//TODO DELETE!
	cout << "type is: " << _type << "\norder is: " << _opOrder
			<<"\nname is: " << _opName << endl;
}


//overridden for SN operation
double S_Operation::numPermutations() {
	int i,j,k ;
	int groupSize;
	double tmp, fact;
	double total = 1.0;
	if (_opOrder > 2 && _type == SN) {
		// In this case - we enumerate over groups of 1, 2, N
		for (i = 1; i <= _mol->_groupNum; i++) {
			groupSize = _mol->getClassSize(i);
			tmp = 0;
			fact = factorial(groupSize);
			// Enumerate over the number of groups of size two
			for (k = 0; k <= (groupSize / 2); k++) {
				// Enumerate over the number of groups of size operationOrder
				for (j = 0; j <= ((groupSize - 2 * k) / _opOrder); j++) {
					tmp += fact/(factorial(groupSize - j * _opOrder - k * 2) *
							pow((double)_opOrder, j) *factorial(j) *
							pow((double)2, k) * factorial(k));
				}
			}
			total *= (tmp);
		}
	} else Operation::numPermutations(); //call the function from the father
	return total;
}

